

export type ListenerFunc = (event: string, args: any) => void

class EventData {
    public event!: string;
    public listener!: ListenerFunc;
    public object: any;
}


export class MessageEventData {
    private events: any = {};

    
    on(event: string, listener: ListenerFunc, object: object) {
        let list: Array<EventData> = this.events[event];
        if (list == null) {
            list = [];
            this.events[event] = list;
        }
        let data: EventData = new EventData();
        data.event = event;
        data.listener = listener;
        data.object = object;
        list.push(data);

        MessageManager.Instance.on(event, listener, object);
    }

    off(event: string) {
        let ebs: Array<EventData> = this.events[event];
        if (!ebs) {
            return;
        }
        for (let eb of ebs) {
            MessageManager.Instance.off(event, eb.listener, eb.object);
        }
        delete this.events[event];
    }

    dispatchEvent(event: string, arg: any = null) {
        MessageManager.Instance.dispatchEvent(event, arg);
    }

    clear() {
        for (let event in this.events) {
            this.off(event);
        }
    }
}

export class MessageManager {
    static readonly Instance: MessageManager = new MessageManager();

    private events: any = {};
    private timeList: any = [];

    on(event: string, listener: ListenerFunc, object: object) {
        if (!event || !listener) {
            cc.warn(`注册【${event}】事件的侦听器函数为空`);
            return;
        }

        let list: Array<EventData> = this.events[event];
        if (list == null) {
            list = [];
            this.events[event] = list;
        }

        let length = list.length;
        for (let i = 0; i < length; i++) {
            let bin = list[i];
            if (bin.listener == listener && bin.object == object) {
                cc.warn(`名为【${event}】的事件重复注册侦听器`);
            }
        }


        let data: EventData = new EventData();
        data.event = event;
        data.listener = listener;
        data.object = object;
        list.push(data);
    }


    once(event: string, listener: ListenerFunc, object: object) {
        let _listener: any = ($event: string, $args: any) => {
            this.off(event, _listener, object);
            _listener = null;
            listener.call(object, $event, $args);
        }
        this.on(event, _listener, object);
    }

    off(event: string, listener: Function, object: object) {
        let list: Array<EventData> = this.events[event];

        if (!list) {
            cc.log(`名为【${event}】的事件不存在`);
            return;
        }

        let length = list.length;
        for (let i = 0; i < length; i++) {
            let bin: EventData = list[i];
            if (bin.listener == listener && bin.object == object) {
                list.splice(i, 1);
                break;
            }
        }

        if (list.length == 0) {
            delete this.events[event];
        }
    }

    dispatchEvent(event: string, args: any = null) {
        let list: Array<EventData> = this.events[event];

        if (list != null) {
            let temp: Array<EventData> = list.concat();
            let length = temp.length;
            for (let i = 0; i < length; i++) {
                let eventBin = temp[i];
                eventBin.listener.call(eventBin.object, event, args);
            }
        }
    }

    sleep(timeout) {
        return new Promise((resolve, reject) => {
            // // let t = setTimeout(() => {
            // //     resolve(null)
            // // }, timeout * 1000)
            // // this.timeList.push(t)
            // cc.director.getScheduler().schedule(() => { resolve(null) }, cc.find("Canvas"), timeout, 1, 0);
            // cc.find("Canvas").getComponent(cc.Component).scheduleOnce(() => { resolve(null) }, timeout)
            cc.tween(cc.find("Canvas"))
                .delay(timeout)
                .call(() => {
                    resolve(null)
                })
                .start()
        })
    }

    stopTime() {
        cc.find("Canvas").stopAllActions();
    }

    stopAllTime() {
        cc.game.pause();
        // cc.director
    }
}